
#include <windows.h>
#include <ceddk.h>
#include "SianoSPI.h"
#include "PxaRegs.h"
#include "pkfuncs.h"
#include <nkintr.h>


//Rock 1118
#include "monahans.h"
#include "xllp_mfp_proc.h"
#include "xllp_mfp_plat.h"
#include "xllp_gpio_plat.h"
#include "xllp_ssp_plat.h"
#include "xllp_gpio_proc.h"
#include "xllp_ost.h"
#include "xllp_i2c_proc.h"
#include "xllp_mfp_rm.h"
#include "GPX_xllp.h"


#define SPI_ACTIVATION_PREAMBLE1 0xc1de0000
#define SPI_ACTIVATION_PREAMBLE2 0xedf151a5
#define SPI_COMMAND_PREAMBLE	 0x7ee75aa5

 typedef struct SmsMsgHdr_S
 {
     UINT16	msgType;
     UINT8	msgSrcId;
     UINT8	msgDstId;
     UINT16	msgLength;	// Length is of the entire message, including header
     UINT16	msgFlags;

 } SmsMsgHdr_ST;


typedef struct SmsMsgData_S
{
	SmsMsgHdr_ST	xMsgHeader;
	UINT32			msgData[1];
} SmsMsgData_ST;

#define SMS_MAX_PAYLOAD_SIZE	240

typedef struct SmsDataDownload_S
{
	SmsMsgHdr_ST	xMsgHeader;
	UINT32			MemAddr;
	UINT32			Payload[SMS_MAX_PAYLOAD_SIZE/4];
} SmsDataDownload_ST;

#define MSG_SMS_GET_VERSION_EX_REQ		668 // A request to get version
#define MSG_SMS_GET_VERSION_EX_RES		669 // A request to get version

#define WM_DRIVER 35
#define MSG_SMS_DATA_DOWNLOAD_REQ		660
#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ	664
#define MSG_SMS_SPI_INT_LINE_SET_REQ	710
#define MSG_SMS_SPI_SET_BUS_WIDTH_REQ	738




#define POLLING_TIMEOUT 500000

//Rock 1118
//define XLLP_SSCR0_SSE  (0x1<<7)         // 1 -- SSP operation is enabled

/*
 * SSP Serial Port Registers
 * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different.
 * PXA255, PXA26x and PXA27x have extra ports, registers and bits.
 */

 /* Common PXA2xx bits first */
#define SSCR0_DataSize(x)  ((x) - 1)	/* Data Size Select [4..16] */
#define SSCR0_Motorola	(0x0 << 4)	/* Motorola's Serial Peripheral Interface (SPI) */

#define SSCR1_RIE	(1 << 0)	/* Receive FIFO Interrupt Enable */
#define SSCR1_TIE	(1 << 1)	/* Transmit FIFO Interrupt Enable */
#define SSCR1_LBM	(1 << 2)	/* Loop-Back Mode */
#define SSCR1_SPO	(1 << 3)	/* Motorola SPI SSPSCLK polarity setting */
#define SSCR1_SPH	(1 << 4)	/* Motorola SPI SSPSCLK phase setting */
#define SSCR1_MWDS	(1 << 5)	/* Microwire Transmit Data Size */
#define SSCR1_TFT	(0x000003c0)	/* Transmit FIFO Threshold (mask) */
#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */
#define SSCR1_RFT	(0x00003c00)	/* Receive FIFO Threshold (mask) */
#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */

#define SSSR_TNF	(1 << 2)	/* Transmit FIFO Not Full */
#define SSSR_RNE	(1 << 3)	/* Receive FIFO Not Empty */
#define SSSR_BSY	(1 << 4)	/* SSP Busy */
#define SSSR_TFS	(1 << 5)	/* Transmit FIFO Service Request */
#define SSSR_RFS	(1 << 6)	/* Receive FIFO Service Request */
#define SSSR_ROR	(1 << 7)	/* Receive FIFO Overrun */

#define SSCR0_RIM		(1 << 22)	/* Receive FIFO Over Run interrupt Mask */
#define SSCR0_NCS		(1 << 21)	/* Network Clock Select */
#define SSCR0_EDSS		(1 << 20)	/* Extended Data Size Select */

/* extra bits in PXA255, PXA26x and PXA27x SSP ports */
#define SSCR1_TRAIL		(1 << 22)	/* Trailing Byte */
#define SSCR1_TSRE		(1 << 21)	/* Transmit Service Request Enable */
#define SSCR1_RSRE		(1 << 20)	/* Receive Service Request Enable */
#define SSCR1_TINTE		(1 << 19)	/* Receiver Time-out Interrupt enable */
#define SSCR1_PINTE		(1 << 18)	/* Peripheral Trailing Byte Interupt Enable */
#define SSCR1_STRF		(1 << 15)	/* Select FIFO or EFWR */
#define SSCR1_EFWR		(1 << 14)	/* Enable FIFO Write/Read */


#define fwmin(a,b)(a<b?a:b)
#define MAX_REG_PATH_SIZE 100
#define MAX_REG_KEY_SIZE 100

//IRQ registration 
#define DEFAULT_IRQ_GPIOXX_2 10

#define SWAP32(x)	( (((x)&0x000000ff) << 24) | \
					 (((x)&0x0000ff00) << 8) |	\
					 (((x)&0x00ff0000) >> 8) |	\
					 (((x)&0xff000000) >> 24))

#define MIN_BUFF_PARTITION 256
#define FW_STEP 4

#define GET_GPIOXX_2_IRQ
#define CONFIGURE_GPIO
#define USE_CONSO_DEFAULT

typedef struct
{
	DWORD					useSSPPort;
	CHAR					DmaDllName[MAX_REG_PATH_SIZE];
#ifdef _SIANO_DMA
	DEVICE_DMA_SERVICE_ST*	dmaService;
#endif
	volatile XLLP_SSP_REGS *sspCtrl;
	DWORD					sspDataRegPhy;
	HANDLE					rxEvent;
	HANDLE					SmsInterruptEvent;
	DWORD					spiSysIntr;
	DWORD					RxInterruptCnt;		//For debug
	BOOL					drvActive;
	HANDLE					RxIST;
	PVOID					intrContext;
	BD_TYPE_E				bdType;
	DWORD					intrPin;
	void(*InterruptCallback)(void*);
	BOOL					endianSwap;
}SPIPHY, *PSPIPHY;


	
//writing to SPI device
static void SSPWriteDWord(PSPIPHY pSpiPhy,DWORD dwVal)
{
	
	if (pSpiPhy->endianSwap)
		dwVal = SWAP32(dwVal);
	pSpiPhy->sspCtrl->ssdr = dwVal;	
}

//reading from SPI device
static DWORD SSPReadDWord(PSPIPHY pSpiPhy)
{
	DWORD v = pSpiPhy->sspCtrl->ssdr;
	if (pSpiPhy->endianSwap)
		v = SWAP32(v);
	return v;
}

//write and read to/from SPI device
static DWORD ReadWriteDWord(PSPIPHY pSpiPhy,DWORD dwInVal)
{
	DWORD dwRetVal;
	DWORD timeout;
	
	timeout = POLLING_TIMEOUT;	
	//Loop while there is any data in the fifo
	while(!(pSpiPhy->sspCtrl->ssr & SSSR_TNF) && timeout--);
	if (timeout == -1)
		return 0;
	SSPWriteDWord(pSpiPhy,dwInVal);
	
	timeout = POLLING_TIMEOUT;
	while(!(pSpiPhy->sspCtrl->ssr & SSSR_RNE) && timeout--);
	if (timeout == -1)
		return 0;
	dwRetVal = SSPReadDWord(pSpiPhy);
	return dwRetVal;
}


static void endOfDmaTransfer(DWORD	transactionId, DWORD status)
{
	DBGMSG( ZONE_PHY,(TEXT("SmsSpi:  DMA transaction end.\r\n")));
	SetEvent((HANDLE)transactionId);
}


static BOOL spiPhyGetRegistrySettings(PVOID Context, PSPIPHY pSpiPhy )
{
	TCHAR*	regKey;
	BOOL	st;
	HKEY	hKey;
	DWORD	dataSize, type;
	SPI_DEVICE_TYPE_E	deviceType;

	
	DWORD SPIINTIRQ = 0;


	regKey = (TCHAR *)LocalAlloc (LPTR, MAX_REG_KEY_SIZE);
	if (regKey == NULL)
	{
		DBGMSG( ZONE_ERROR,(TEXT("Siano SPI - ERROR!! Allocating memory for registry reading failed.\r\n")));
		return FALSE;
	}


	st = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCWSTR)Context, 0, 0, &hKey);						
	if(st != ERROR_SUCCESS)
	{
		DBGMSG( ZONE_ERROR,(TEXT("Siano SPI - ERROR!! Could not open registry key.\r\n")));
		LocalFree(regKey);
		return (FALSE);
	}

	dataSize=MAX_REG_KEY_SIZE;
	st = RegQueryValueEx(	hKey, 
							TEXT("Key"), 
							NULL,
							&type, 
							(LPBYTE)regKey, 
							&dataSize);
	
	RegCloseKey(hKey);
	if(st!=ERROR_SUCCESS)	
	{
		DBGMSG( ZONE_ERROR,(TEXT("Siano SPI - ERROR!! Could not get registry key name.\r\n")));
		LocalFree(regKey);
		return (FALSE);
	}
	
	// Now - read all the needed parameters for the driver from the registry.


	st = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKey, 0, 0, &hKey);
	if(st != ERROR_SUCCESS)
	{
		DBGMSG( ZONE_ERROR,(TEXT("Siano SPI - ERROR!! Could not open registry key.\r\n")));
		LocalFree(regKey);
		return (FALSE);
	}


	dataSize=MAX_REG_PATH_SIZE;
	st = RegQueryValueEx( hKey, 
						  L"DmaServicesPlugin", 
						  0, 
						  &type, 
						  (LPBYTE)&pSpiPhy->DmaDllName, 
						  &dataSize);
	if(st != ERROR_SUCCESS)
	{ //Set default value if registry entry is not found.
		pSpiPhy->DmaDllName[0] = 0;
	}

	
	dataSize = sizeof(pSpiPhy->useSSPPort);
	st = RegQueryValueEx( hKey, 
					  L"useSSPPort", 
					  0, 
					  &type, 
					  (LPBYTE)&pSpiPhy->useSSPPort, 
					  &dataSize);

	if(st != ERROR_SUCCESS)
	{ //Set default value if registry entry is not found.
		pSpiPhy->useSSPPort = 1;
	}
/*
	dataSize = sizeof(pSpiPhy->spiSysIntr);
	st = RegQueryValueEx( hKey, 
					  L"useSysIntr", 
					  0, 
					  &type, 
					  (LPBYTE)&pSpiPhy->spiSysIntr, 
					  &dataSize);

	if(st != ERROR_SUCCESS)
	{ //Set default value if registry entry is not found.
		pSpiPhy->spiSysIntr = 34;
	}*/

	SPIINTIRQ= IRQ_GPIO_SHARE(XLLP_GPIO_CMMB_INT);


	RETAILMSG(1,(TEXT("[Siano]Get the IRQ =%d\n"), SPIINTIRQ));	        

	if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &SPIINTIRQ,sizeof(DWORD),&(pSpiPhy->spiSysIntr),sizeof(DWORD), NULL))
    {
        // invalid SDIO SYSINTR value!
        RETAILMSG(1,(TEXT("[ERR]Siano :Error obtaining CMMB SYSINTR value!\n")));	        
        pSpiPhy->spiSysIntr = SYSINTR_UNDEFINED;
        return 0;
    }

/*
	
	if (pSpiPhy->spiSysIntr == 0xffff)
	{
		DWORD Irq_GpioXX_2;
		Irq_GpioXX_2 = DEFAULT_IRQ_GPIOXX_2;//consonance irq number
		DBGMSG( ZONE_INIT,(TEXT("Irq Number = %d!!!\r\n"),DEFAULT_IRQ_GPIOXX_2));
		if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq_GpioXX_2, sizeof(DWORD), &pSpiPhy->spiSysIntr, sizeof(DWORD), NULL))
		{
			DBGMSG( ZONE_INIT, (TEXT("SPI : IOCTL_HAL_REQUEST_SYSINTR failed (x%08x)\r\n"), GetLastError()));
		}
		else
		{
			DBGMSG( ZONE_INIT, (TEXT("SPI : IOCTL_HAL_REQUEST_SYSINTR Succeded SysIntr %d\r\n"), pSpiPhy->spiSysIntr));
		}
	}
*/



	dataSize = sizeof(deviceType);
	st = RegQueryValueEx( hKey, 
					  L"DeviceType", 
					  0, 
					  &type, 
					  (LPBYTE)&deviceType, 
					  &dataSize);

	if(st != ERROR_SUCCESS)
	{ //Set default value if registry entry is not found.
		deviceType = BD_TYPE_SPI_VEGA;
	}

    

	RETAILMSG(1,(TEXT("Set pSpiPhy->bdType =%d\n"), deviceType));	
	
	switch(deviceType)
	{
		case SPI_DEVICE_NOVA:
			pSpiPhy->bdType = BD_TYPE_SPI_NOVA;
			break;
		case SPI_DEVICE_VEGA:
			pSpiPhy->bdType = BD_TYPE_SPI_VEGA;
			break;
		default:
			pSpiPhy->bdType = BD_TYPE_SPI_STELLAR;
			break;
	}

	dataSize = sizeof(pSpiPhy->intrPin);
	st = RegQueryValueEx( hKey, 
					  L"IntrPin", 
					  0, 
					  &type, 
					  (LPBYTE)&pSpiPhy->intrPin, 
					  &dataSize);

	if(st != ERROR_SUCCESS)
	{ //Set default value if registry entry is not found.
		if (pSpiPhy->bdType != BD_TYPE_SPI_VEGA)
			pSpiPhy->intrPin = 16;
		else
			pSpiPhy->intrPin = 26;
	}

    pSpiPhy->intrPin = 19;
    RETAILMSG(1,(TEXT("Set Vega int pin =%d\n"), pSpiPhy->intrPin));
	
	st = RegCloseKey(hKey);
	if(st!=ERROR_SUCCESS)	
	{
		DBGMSG( ZONE_ERROR,(TEXT("Siano SPI - ERROR!! Could not get registry key name.\r\n")));
		LocalFree(regKey);
		return (FALSE);
	}

	LocalFree(regKey);
	return (TRUE);

}


#ifdef _SIANO_DMA

static BOOL	activateDMAService(PSPIPHY pSpiPhy)
{
	DMA_INIT_PARAMS_ST dmaSetUp;
	
	if (pSpiPhy->DmaDllName[0] == 0)
	{
		DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: activateDMAService() There is no DMA service name.\r\n")));
		return FALSE;
	}
	
	pSpiPhy->dmaService = (DEVICE_DMA_SERVICE_ST*)LocalAlloc(LPTR, sizeof(DEVICE_DMA_SERVICE_ST));
	if (pSpiPhy->dmaService == NULL)
	{
		DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: activateDMAService() Could not allocate DMA service structure.\r\n")));
		return FALSE;
	}
	
	pSpiPhy->dmaService->hdl = LoadLibrary((LPCWSTR)pSpiPhy->DmaDllName);
	if (pSpiPhy->dmaService->hdl == NULL)
	{
		DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: activateDMAService() Could not load DMA service library.\r\n")));
		LocalFree(pSpiPhy->dmaService);
		pSpiPhy->dmaService = NULL;
		return FALSE;
	}

	pSpiPhy->dmaService->dmaSetUpChannel = (DMA_SetUpChannelF)GetProcAddress(pSpiPhy->dmaService->hdl, TEXT("DMA_SetUpChannel"));
	pSpiPhy->dmaService->dmaConfigChannel = (DMA_ConfigChannelF)GetProcAddress(pSpiPhy->dmaService->hdl, TEXT("DMA_ConfigChannel"));
	pSpiPhy->dmaService->dmaRemoveChannel = (DMA_RemoveChannelF)GetProcAddress(pSpiPhy->dmaService->hdl, TEXT("DMA_RemoveChannel"));
	if (pSpiPhy->dmaService->dmaSetUpChannel == NULL ||
		pSpiPhy->dmaService->dmaConfigChannel == NULL ||
		pSpiPhy->dmaService->dmaRemoveChannel == NULL)
	{
		DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: activateDMAService() Could not find DMA library routines.\r\n")));
		FreeLibrary(pSpiPhy->dmaService->hdl);
		LocalFree(pSpiPhy->dmaService);
		pSpiPhy->dmaService = NULL;
		return FALSE;
	}


	dmaSetUp.flags = DMA_USE_HW_FLOW_CTRL;
	if (pSpiPhy->useSSPPort == 1)	
		dmaSetUp.dmaReq = SSP1_TX_CMR;
	else if (pSpiPhy->useSSPPort == 2)	
		dmaSetUp.dmaReq = SSP2_TX_CMR;
    else if (pSpiPhy->useSSPPort == 3)	
        dmaSetUp.dmaReq = SSP3_TX_CMR;
    else if (pSpiPhy->useSSPPort == 4)	
        dmaSetUp.dmaReq = SSP4_TX_CMR;
	dmaSetUp.burstSize = DMA_BURST_8_BYTES;
	dmaSetUp.busWidth = DMA_BUS_WIDTH_4_BYTE;
	pSpiPhy->dmaService->txDmaDevice=pSpiPhy->dmaService->dmaSetUpChannel(&dmaSetUp);

	dmaSetUp.flags = DMA_USE_HW_FLOW_CTRL;
    if (pSpiPhy->useSSPPort == 1)	
        dmaSetUp.dmaReq = SSP1_RX_CMR;
    else if (pSpiPhy->useSSPPort == 2)	
        dmaSetUp.dmaReq = SSP2_RX_CMR;
    else if (pSpiPhy->useSSPPort == 3)	
        dmaSetUp.dmaReq = SSP3_RX_CMR;
    else if (pSpiPhy->useSSPPort == 4)	
        dmaSetUp.dmaReq = SSP4_RX_CMR;
	dmaSetUp.burstSize = DMA_BURST_8_BYTES;
	dmaSetUp.busWidth = DMA_BUS_WIDTH_4_BYTE;
	pSpiPhy->dmaService->rxDmaDevice=pSpiPhy->dmaService->dmaSetUpChannel(&dmaSetUp);
	return TRUE;
}


static BOOL	deactivateDMAService(PSPIPHY pSpiPhy)
{
	if (pSpiPhy->dmaService != NULL)
	{
		if (pSpiPhy->dmaService->rxDmaDevice)
			pSpiPhy->dmaService->dmaRemoveChannel(pSpiPhy->dmaService->rxDmaDevice);
		if (pSpiPhy->dmaService->txDmaDevice)
			pSpiPhy->dmaService->dmaRemoveChannel(pSpiPhy->dmaService->txDmaDevice);
		if (pSpiPhy->dmaService->hdl)
			FreeLibrary(pSpiPhy->dmaService->hdl);
		LocalFree(pSpiPhy->dmaService);
		pSpiPhy->dmaService = NULL;
	}
	return TRUE;
}
#endif

VOID SpiRxIST(PVOID pArg)
{
	PSPIPHY pSpiPhy = (PSPIPHY)pArg;

	pSpiPhy->RxInterruptCnt = 0;
	while (1)
	{
		WaitForSingleObject(pSpiPhy->SmsInterruptEvent,INFINITE);
		if (pSpiPhy->drvActive == FALSE)
		{
			return;
		}
		pSpiPhy->RxInterruptCnt++;		
		if (pSpiPhy->InterruptCallback)
			pSpiPhy->InterruptCallback(pSpiPhy->intrContext);
		
		InterruptDone(pSpiPhy->spiSysIntr);
		
	}
}

////////////////////////////   Internal fucntions /////////////////////////////////


/*************************************************************************************
FUNCTION NAME:	WriteFW

DESCRIPTION:	the actual writing to the firmwere
*************************************************************************************/


VOID WriteFWtoStellar(PSPIPHY pSpiPhy,BYTE* pFW,DWORD Len)
{
	DWORD Padding;
	DWORD Cnt = 0;
	DWORD *pPos = (DWORD*)pFW;
	int LeftOver;

	if (pSpiPhy->bdType != BD_TYPE_SPI_STELLAR)
		return;

	//Data Must be sent in 256 Bytes chuncks --- CHANGED: Pre DMA init in Siano device, pass the exact file size.
	Padding = Len%MIN_BUFF_PARTITION;
	if(Padding)
		Padding = MIN_BUFF_PARTITION - Padding;//to complete to 256;
	DBGMSG( ZONE_INFO, (TEXT("SmsSpi: WriteFW :Len %d bytes Padding %d Bytes\r\n"),Len,Padding));

	//1st Phaze
	DBGMSG( ZONE_INFO, (TEXT("SmsSpi: WriteFW :Entering Phaze 1\r\n")));
	while((Cnt+FW_STEP)<=Len)
	{
		//actual Device Writing
		//no need checking the data received from the device
			
		DWORD ret = ReadWriteDWord(pSpiPhy,*pPos);
		//DBGMSG( ZONE_INFO,(TEXT("r:0x%x\r\n"),dwval));
		//Change Stats
		Cnt+=fwmin(FW_STEP,Len-Cnt);
		pPos++;//+4

	}

	//2nd Phaze
	//Check if we have left over data we didn't send
	DBGMSG( ZONE_INFO, (TEXT("SPI!WriteFW :Entering Phaze 2\r\n")));
	LeftOver = (Len - Cnt);
	DBGMSG( ZONE_INFO, (TEXT("SPI!WriteFW :LeftOver Data Len %d Bytes\r\n"),LeftOver));
	if (LeftOver>0)
	{
		DWORD dwval;
		pPos = (DWORD*)(pFW+Cnt);
		dwval= ReadWriteDWord(pSpiPhy,*pPos);
	}
	Sleep(100);

}


static BOOL enableDisableSSPClock(PSPIPHY pSpiPhy, BOOL enable)
{

    volatile XLLP_CLKMGR_T    *v_pClkRegs		 = NULL;
	PHYSICAL_ADDRESS    PhysicalBase;

	PhysicalBase.QuadPart = MONAHANS_BASE_REG_PA_CLKMGR;

	v_pClkRegs= (XLLP_CLKMGR_T *)MmMapIoSpace(PhysicalBase,sizeof(XLLP_CLKMGR_T),FALSE);

	if (!v_pClkRegs)
	{
		return FALSE;
	}

    switch (pSpiPhy->useSSPPort)
    {
    case 1:
		if (enable)
			SSP_CLK_ENABLE |=   XLLP_CLKEN_SSP1;
		else
			SSP_CLK_ENABLE &=   ~XLLP_CLKEN_SSP1;
        break;
    case 2:
		if (enable)
			SSP_CLK_ENABLE |=   XLLP_CLKEN_SSP2;
		else
			SSP_CLK_ENABLE &=   ~XLLP_CLKEN_SSP2;
        break;
    case 3:
		if (enable)
			SSP_CLK_ENABLE |=   XLLP_CLKEN_SSP3;
		else
			SSP_CLK_ENABLE &=   ~XLLP_CLKEN_SSP3;
        break;
    default: //other than 4 will fail earlier therefore default = 4.
		if (enable)
			SSP_CLK_ENABLE |=   XLLP_CLKEN_SSP4;
		else
			SSP_CLK_ENABLE &=   ~XLLP_CLKEN_SSP4;
    }
    RETAILMSG(1, (TEXT("[Siano]CLK MGR Reg: %x\r\n"), SSP_CLK_ENABLE));
	MmUnmapIoSpace((PVOID)v_pClkRegs,sizeof(XLLP_CLKMGR_T));
	return TRUE;

}

void prepareForFWDnl(void* context)
{
// Note: must be called from the context of SPI_IOControl
    PSPIPHY pSpiPhy = (PSPIPHY)context;
    DWORD msgBuf[sizeof(SmsMsgHdr_ST) + (sizeof(DWORD) * 3)];
    SmsMsgData_ST* setIntMsg = (SmsMsgData_ST*)msgBuf;
    //DWORD index,dwRet = 0;
	pSpiPhy->sspCtrl->sscr0 &= ~XLLP_SSCR0_SSE;
    /* Reduce the SPI Clock to download speed.*/
    if (!enableDisableSSPClock(pSpiPhy, FALSE))
    {
        return;
    }
    // Set register SSCR0
    pSpiPhy->sspCtrl->sscr0 &= 0xfff000ff;
    pSpiPhy->sspCtrl->sscr0 |=6<<8; // Divide the clock by 6
    if (!enableDisableSSPClock(pSpiPhy, TRUE))
    {
        return;
    }
    pSpiPhy->sspCtrl->sscr0 |=XLLP_SSCR0_SSE;

    ReadWriteDWord(pSpiPhy,SPI_ACTIVATION_PREAMBLE1);
    ReadWriteDWord(pSpiPhy,SPI_ACTIVATION_PREAMBLE2);

#if 0	
while(1)
{

	setIntMsg->xMsgHeader.msgType = MSG_SMS_GET_VERSION_EX_REQ;
	setIntMsg->xMsgHeader.msgDstId = 11;			// to MSGPROC_TASK
	setIntMsg->xMsgHeader.msgSrcId = WM_DRIVER; 	// to MSGPROC_TASK
	setIntMsg->xMsgHeader.msgFlags = 0;
	setIntMsg->xMsgHeader.msgLength = sizeof(SmsMsgHdr_ST) +  sizeof(UINT32);
	SPI_Write((DWORD)pSpiPhy->intrContext,setIntMsg,setIntMsg->xMsgHeader.msgLength);

    for(index=0;index<(256>>2);index++)
    {
		dwRet = ReadWriteDWord(pSpiPhy, 0);
		//if(dwRet!=0)
			DBGMSG(1,(TEXT("[Siano]:Read Version data:%x\r\n"),dwRet));
    }
	Sleep(1000);

}	
#endif
    setIntMsg->xMsgHeader.msgType = MSG_SMS_SPI_INT_LINE_SET_REQ;
    setIntMsg->xMsgHeader.msgDstId = 11;			// to MSGPROC_TASK
    setIntMsg->xMsgHeader.msgSrcId = WM_DRIVER;		// to MSGPROC_TASK
    setIntMsg->xMsgHeader.msgFlags = 0;
    setIntMsg->xMsgHeader.msgLength = sizeof(SmsMsgHdr_ST) + 3 * sizeof(UINT32);
    setIntMsg->msgData[0] = 0;						// Main Spi Controller (0) 
    setIntMsg->msgData[1] = pSpiPhy->intrPin;		// Interrupt GPIO.
    setIntMsg->msgData[2] = 20;						// Default pulse width.

	SPI_Write((DWORD)pSpiPhy->intrContext,setIntMsg,setIntMsg->xMsgHeader.msgLength);
}

void fwDnlComplete(void* context)
{
// Note: must be called from the context of SPI_IOControl
    PSPIPHY pSpiPhy = (PSPIPHY)context;
	DWORD msgBuf[sizeof(SmsMsgHdr_ST) + (sizeof(DWORD) * 2)];
    SmsMsgData_ST* setWidth = (SmsMsgData_ST*)msgBuf;

    setWidth->xMsgHeader.msgType = MSG_SMS_SPI_SET_BUS_WIDTH_REQ;
    setWidth->xMsgHeader.msgDstId = 11;			// to MSGPROC_TASK
    setWidth->xMsgHeader.msgSrcId = WM_DRIVER;	// to MSGPROC_TASK
    setWidth->xMsgHeader.msgFlags = 0;
    setWidth->xMsgHeader.msgLength = sizeof(SmsMsgHdr_ST) + 2 * sizeof(UINT32);
    setWidth->msgData[0] = 0;					// Main Spi Controller (0) 
    setWidth->msgData[1] = 2;					// FDMA_BUS_32

	SPI_Write((DWORD)pSpiPhy->intrContext,setWidth,setWidth->xMsgHeader.msgLength);
	pSpiPhy->endianSwap = FALSE;
	Sleep(20);

	pSpiPhy->sspCtrl->sscr0 &= ~XLLP_SSCR0_SSE;
    /* Increase the SPI Clock to working speed.*/
    if (!enableDisableSSPClock(pSpiPhy, FALSE))
    {
        return;
    }
    // Set register SSCR0
    pSpiPhy->sspCtrl->sscr0 &= 0xfff000ff;
//    pSpiPhy->sspCtrl->sscr0 |=1<<27; // Pxa310LV change freq to 26M
//    if (App == BD_APP_ISDBT)
        pSpiPhy->sspCtrl->sscr0 |=3<<8; // Divide the clock by 4 for ISDBT.
    if (!enableDisableSSPClock(pSpiPhy, TRUE))
    {
        return; 
    }
    pSpiPhy->sspCtrl->sscr0 |=XLLP_SSCR0_SSE;
}

void smsspibus_xfer(void* context, 
				   unsigned char * txbuf, unsigned long txbuf_phy_addr, 
				   unsigned char* rxbuf, unsigned long rxbuf_phy_addr, 
				   int len)
{
	PSPIPHY pSpiPhy = (PSPIPHY)context;
	DWORD timeout;
	DWORD* pdw;
	if (txbuf)
	{
		DBGMSG( ZONE_PHY, (TEXT("transfer buf starting with: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x.\r\n"), txbuf[0], 
		txbuf[1], txbuf[2], txbuf[3], txbuf[4], txbuf[5], txbuf[6], txbuf[7]));
	}
	if (len & 0xff)
	{
		timeout = 0;
		len = len + timeout;
		DBGMSG( ZONE_ERROR, (TEXT("Bad message length allignment!!!!!!!!!!!!!!!\r\n")));
	}
#ifdef _SIANO_DMA
	if (pSpiPhy->dmaService == NULL)
	{ //No DMA service - copy using CPU
#endif
		//Loop as long as the TX packet has not been completly trasmitterd, or 
		//until the RX FIFO is emty
		DBGMSG( ZONE_INFO | ZONE_PHY, (TEXT("transfer %d bytes without DMA. rxbuf = 0x%x \r\n"), len, (DWORD)rxbuf));
		pdw = (DWORD*)rxbuf;
		while(len > 0)
		{
			//Loop while there is any data in the fifo
			while(!(pSpiPhy->sspCtrl->ssr & SSSR_TNF));
			if(txbuf)
			{
				DWORD sb = *((DWORD*)txbuf);
				SSPWriteDWord(pSpiPhy,sb);
				txbuf+=4;
			}
			else
			{
				SSPWriteDWord(pSpiPhy,0);						
			}
			timeout = POLLING_TIMEOUT;
			while(!(pSpiPhy->sspCtrl->ssr & SSSR_RNE) && timeout--);
			if (timeout == -1)	//This is for debugginf - timeout should never expire. If it does - SSP controler is not working.
				timeout = 0;
			*pdw = SSPReadDWord(pSpiPhy);
			pdw++;//pointer to DWORD inc by 4
			len-=4;					
		}
#ifdef _SIANO_DMA
	}
	else // Using DMA
	{
		DMA_PARAMS_ST dmaParams;
		int i, tmp;

		DBGMSG( ZONE_INFO | ZONE_PHY, (TEXT("transfer %d bytes with DMA.\r\n"), len));
		if(txbuf)
		{
			//Set the Tx buffer DMA transaction.
			if (pSpiPhy->endianSwap)
			{
				for (i = 0; i < (len+3)>>2; i++)
					((DWORD*)txbuf)[i] = SWAP32(((DWORD*)txbuf)[i]);
			}
		}

		/*Activate the DMA for the recieve of bytes*/
		dmaParams.srcAddr = pSpiPhy->sspDataRegPhy;
		dmaParams.dstAddr = rxbuf_phy_addr;
		dmaParams.len = len;
		dmaParams.flags = DMA_USE_SRC_FLOW_CONTROL | DMA_INC_DST_ADDR;
		dmaParams.transactionId = (DWORD)pSpiPhy->rxEvent;
		dmaParams.callBack = endOfDmaTransfer;
		pSpiPhy->dmaService->dmaConfigChannel((LPVOID)pSpiPhy->dmaService->rxDmaDevice, &dmaParams);
		DBGMSG( ZONE_PHY, (TEXT("DMA transfer src=0x%x, dst=0x%x, len=%d \r\n"), dmaParams.srcAddr, dmaParams.dstAddr, len));

		/*Activate the DMA for the transmit of bytes*/
		if(txbuf)
		{
			dmaParams.srcAddr = txbuf_phy_addr;
			dmaParams.flags = DMA_USE_DST_FLOW_CONTROL | DMA_INC_SRC_ADDR;
		}
		else
		{
			dmaParams.srcAddr = txbuf_phy_addr + 8; //To avoid sending preamble - we don't send the begining of the buffer.
			dmaParams.flags = DMA_USE_DST_FLOW_CONTROL;
		}
		dmaParams.dstAddr = pSpiPhy->sspDataRegPhy;
		dmaParams.len = len;
		dmaParams.transactionId = 0;
		dmaParams.callBack = NULL;
		pSpiPhy->dmaService->dmaConfigChannel((LPVOID)pSpiPhy->dmaService->txDmaDevice, &dmaParams);
		DBGMSG( ZONE_PHY, (TEXT("DMA transfer src=0x%x, dst=0x%x, len=%d \r\n"), dmaParams.srcAddr, dmaParams.dstAddr, len));

		// Moving 256 Bytes through SPI using 6.5Mbps takes ~0.3mS, so we wait much longer than that.
		if (WaitForSingleObject(pSpiPhy->rxEvent, 5000) == WAIT_OBJECT_0)
		{
			DBGMSG( ZONE_PHY, (TEXT("-----------DMA transfer ended.\r\n")));
			if (pSpiPhy->endianSwap)
			{
				for (i = 0; i < len>>2; i++)
				{
					tmp =((DWORD*)rxbuf)[i];
					((DWORD*)rxbuf)[i] =  SWAP32(tmp);
				}
				DBGMSG( ZONE_PHY, (TEXT("Data reveresed.\r\n")));
			}
		}
		else
			DBGMSG( ZONE_ERROR, (TEXT("SPI!Read from device :Recieved Timeout for DMA transfer.\r\n")));
	}
#endif
	DBGMSG( ZONE_PHY, (TEXT("Transfer complete.\r\n")));
}



void smsspiphy_deinit(PVOID context)
{
	DWORD	exitCode;
	PSPIPHY pSpiPhy = (PSPIPHY)context;
	if (pSpiPhy)
	{
		pSpiPhy->drvActive = FALSE;
		if (pSpiPhy->RxIST)
		{
			if (pSpiPhy->SmsInterruptEvent) // Set an event to start the thread.
				SetEvent(pSpiPhy->SmsInterruptEvent);
			CloseHandle(pSpiPhy->RxIST);
			while (GetExitCodeThread(pSpiPhy->RxIST, &exitCode) == STILL_ACTIVE);
			pSpiPhy->RxIST = NULL;
		}
#ifdef _SIANO_DMA
		if (pSpiPhy->dmaService)
		{
			deactivateDMAService(pSpiPhy);
		}
#endif
		if (pSpiPhy->rxEvent)
		{
			CloseHandle(pSpiPhy->rxEvent);
			pSpiPhy->rxEvent = NULL;

		}
		if (pSpiPhy->SmsInterruptEvent)
		{
			CloseHandle(pSpiPhy->SmsInterruptEvent);
			pSpiPhy->SmsInterruptEvent = NULL;

		}
		
		LocalFree(pSpiPhy);
	}
#ifdef GET_GPIOXX_2_IRQ
	//disable the hardware interrupt and to deregister the event 
	InterruptDisable(pSpiPhy->spiSysIntr);
#endif						  
	//cancel all Threads...ISRThread
	//cancel all Events...

//unmapping all physical addresses used to access register....
	//unmapping SSP registers
	MmUnmapIoSpace((PVOID)pSpiPhy->sspCtrl ,sizeof(XLLP_SSP_REGS));
	//unmapping CLK registers	

}


static XLLP_UINT_T ssp_mfp_list []={
	XLLP_MFP_SSP_CMMB_SCLK_OFFSET,
	XLLP_MFP_SSP_CMMB_FRM_OFFSET,
	XLLP_MFP_SSP_CMMB_TXD_OFFSET,
	XLLP_MFP_SSP_CMMB_RXD_OFFSET,
	XLLP_MFP_CMMB_LDO_EN_OFFSET,
	XLLP_MFP_CMMB_IRQ_OFFSET,
	XLLP_MFP_PIN_EOLIST_MARKER 
};

#define XLLP_MFP_RM_ID_XLLP_CMMB     XLLP_MFP_RM_ID_XLLP_BASE+0x20


XLLP_MFP_RM_DB_ID_T CMMB_MfpRmDBID = XLLP_MFP_RM_ID_XLLP_CMMB;


void* smsspiphy_init(void* Context, void(*smsspi_interruptHandler)(void*), PVOID intrContext)
{

	DWORD SPICDSysIntr;
	HANDLE m_MfpRMDbHandle;
    BOOL bFirstInit = FALSE;
	P_XLLP_MFP_RM_DB_ID_T m_pMfpRMDb;
	XLLP_STATUS_T status = XLLP_STATUS_SUCCESS;

	
	PHYSICAL_ADDRESS    PhysicalBase;

#ifdef CONFIGURE_GPIO	
    volatile XLLP_GPIO_T            *v_pGPIORegisters;
    volatile UINT32                 *v_pMFPRRegisters = NULL;
    volatile P_XLLP_OST_T           v_pOSTRegisters = NULL;
	volatile P_XLLP_I2C_T           v_pI2CRegisters = NULL;
#endif


	PSPIPHY pSpiPhy = (PSPIPHY)LocalAlloc(LPTR,sizeof(SPIPHY));

	pSpiPhy->intrContext = intrContext;
	spiPhyGetRegistrySettings(Context, pSpiPhy);
#ifdef _SIANO_DMA
    activateDMAService(pSpiPhy);
#endif
	pSpiPhy->InterruptCallback = smsspi_interruptHandler;
	pSpiPhy->drvActive = TRUE;
	pSpiPhy->endianSwap = TRUE;

	pSpiPhy->SmsInterruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (pSpiPhy->SmsInterruptEvent == NULL)
	{
		DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: smsspiphy_init() failed to create SmsInterruptEvent event.\r\n")));
		smsspiphy_deinit(pSpiPhy);
		return NULL;
	}
	DBGMSG(ZONE_INFO, (TEXT("SmsSpi: Interrupt event create: 0x%x.\r\n"), pSpiPhy->SmsInterruptEvent));

	pSpiPhy->rxEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (pSpiPhy->rxEvent == NULL)
	{
		DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: smsspiphy_init() failed to create rxEvent event.\r\n")));
		smsspiphy_deinit(pSpiPhy);
		return NULL;
	}


    switch (pSpiPhy->useSSPPort)
    {
    case 1:
		PhysicalBase.QuadPart = MONAHANS_BASE_REG_PA_SSP1;
		DBGMSG( ZONE_INFO,(TEXT("SmsSpi: smsspiphy_init() using  SSP1.\r\n")));
        break;
    case 2:
		PhysicalBase.QuadPart = MONAHANS_BASE_REG_PA_SSP2;
		DBGMSG( ZONE_INFO,(TEXT("SmsSpi: smsspiphy_init() using   SSP2.\r\n")));
        break;
    case 3:
		PhysicalBase.QuadPart = MONAHANS_BASE_REG_PA_SSP3;
		DBGMSG( ZONE_INFO,(TEXT("SmsSpi: smsspiphy_init() using  SSP3\r\n")));
        break;
    case 4:
        PhysicalBase.QuadPart = MONAHANS_BASE_REG_PA_SSP4;
        DBGMSG( ZONE_INFO,(TEXT("SmsSpi: smsspiphy_init() using  SSP4\r\n")));
        break;
    default:
        DBGMSG( ZONE_ERROR,(TEXT("SmsSpi: smsspiphy_init() Unsupported SSP port.\r\n")));
        smsspiphy_deinit(pSpiPhy);
        return NULL;
    }


	DBGMSG( ZONE_INFO,(TEXT("SmsSpi: smsspiphy_init() mapping SSP controlles at 0x%x.\r\n"), PhysicalBase.LowPart));
    pSpiPhy->sspCtrl = (volatile XLLP_SSP_REGS *)MmMapIoSpace(PhysicalBase,sizeof(XLLP_SSP_REGS),FALSE);
	if (!pSpiPhy->sspCtrl)
	{
		DBGMSG( ZONE_INFO,(TEXT("[ERR]smsspiphy_init() mapping SSP Error\r\n")));	
		smsspiphy_deinit(pSpiPhy);
		return NULL;
	}
	pSpiPhy->sspDataRegPhy = PhysicalBase.LowPart + ((DWORD)(&pSpiPhy->sspCtrl->ssdr) - (DWORD)(pSpiPhy->sspCtrl));
	DBGMSG( ZONE_INFO,(TEXT("SmsSpi: SSP maped to 0x%x. (physical=0x%x)\r\n"), (DWORD)pSpiPhy->sspCtrl, pSpiPhy->sspDataRegPhy));
	
#ifdef CONFIGURE_GPIO	

    PhysicalBase.QuadPart = MONAHANS_BASE_REG_PA_MFP;
    v_pMFPRRegisters = (volatile  *)MmMapIoSpace(PhysicalBase,MFPR_MEMORY_SPACE, FALSE);
	RETAILMSG(1, (TEXT("phy_init v_pMFPRRegisters = %x\r\n"), v_pMFPRRegisters));

	PhysicalBase.QuadPart = MONAHANS_BASE_REG_PA_GPIO;
    v_pGPIORegisters = (XLLP_GPIO_T  *)MmMapIoSpace(PhysicalBase,sizeof(XLLP_GPIO_T), FALSE);
    RETAILMSG(1, (TEXT("phy_init v_pGPIORegisters = %x\r\n"), v_pGPIORegisters));

	PhysicalBase.QuadPart = MONAHANS_BASE_REG_PA_OST;

    v_pOSTRegisters=(XLLP_OST_T *)MmMapIoSpace(PhysicalBase, sizeof(XLLP_OST_T), FALSE);
	if (v_pOSTRegisters==NULL)
	{
		RETAILMSG(1, (TEXT("PMUAllocateReg:MmMapIoSpace Fail\r\n")));
		return FALSE;
	}	

	PhysicalBase.QuadPart = MONAHANS_BASE_REG_PA_I2C;
	v_pI2CRegisters=(XLLP_I2C_T *)MmMapIoSpace(PhysicalBase, sizeof(XLLP_I2C_T), FALSE);
	if (v_pI2CRegisters==NULL)
	{
		RETAILMSG(1, (TEXT("PMUAllocateReg:MmMapIoSpace Fail\r\n")));
		return FALSE;
	}	


//Rock 1118
//Power Up SMS1180
	if(XLLP_STATUS_SUCCESS!=XllpGpioExpanderSetOutputLevel(v_pI2CRegisters,v_pOSTRegisters, XLLP_GPIO_CMMB_LDO_EN, XLLP_HI ))
	{
		RETAILMSG(1, (_T("Set XLLP_GPIO_TV_POWERON HI Error\r\n")));
	}
		if(XLLP_STATUS_SUCCESS!=XllpGpioExpanderSetOutputLevel(v_pI2CRegisters,v_pOSTRegisters, XLLP_GPIO_CMMB_PDN, XLLP_HI ))
	{
		RETAILMSG(1, (_T("Set XLLP_GPIO_TV_POWERON HI Error\r\n")));
	}

	RETAILMSG(1, (TEXT("[Siano] POWER ON SMS1180\r\n")));

	m_MfpRMDbHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
	0, XLLP_MFP_RM_DB_SIZE, MFPRMDB_SHARED_FILENAME );
	

	if (NULL == m_MfpRMDbHandle)        
	{
		RETAILMSG(1, (TEXT("[T_T] Fail to CreateFileMapping(MFPRMDB_SHARED_FILENAME)! \r\n")));     
		return FALSE; 
	} 
	else 
	{
		/*Get information about whether or not the first time we create the Memory-Mapping-File */
		if (ERROR_ALREADY_EXISTS != GetLastError())
		{
			/*OK,Now we know that this is the first initialization of this Memory-Mapping-File */
			RETAILMSG(1, (TEXT("[^_^] First call of CreateFileMapping(MFPRMDB_SHARED_FILENAME)! \r\n")));     
			bFirstInit = TRUE;      
		} 
		else 
		{
			/*It shows that other driver already setup the Memory-Mapping-File*/
			RETAILMSG(1, (TEXT("[^_^] Sequent call of CreateFileMapping(MFPRMDB_SHARED_FILENAME)! \r\n")));
			bFirstInit = FALSE;
		}

	}


	m_pMfpRMDb = (P_XLLP_MFP_RM_DB_ID_T) MapViewOfFile(m_MfpRMDbHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
	if (NULL == m_pMfpRMDb )
	{
		RETAILMSG(1, (TEXT("[T_T] Fail to MapViewOfFile()!\r\n")));
		return FALSE;
	}


	if (TRUE == bFirstInit) 
	{
		/*We  Need to Initialize RM */    
		if (XLLP_STATUS_SUCCESS != XllpMfpResourceManagerInit(m_pMfpRMDb)) 
		{
			RETAILMSG(1, (TEXT("[T_T] Fail to XllpMfpResourceManagerInit()!\r\n")));
			return FALSE; 
		}
	}


		status = XllpMfpResourceManager_List(m_pMfpRMDb,
                         ssp_mfp_list,
                         CMMB_MfpRmDBID, XLLP_SET);

	if (XLLP_STATUS_SUCCESS != status)
	{
		RETAILMSG(1, (TEXT("[T_T] Fail to XllpMfpResourceManager_List()!\r\n")));
		return FALSE; 
	}


	XllpMfpSetAfDs((P_XLLP_VUINT32_T)v_pMFPRRegisters, XLLP_MFP_CMMB_IRQ_OFFSET, XLLP_MFP_CMMB_IRQ_AF, XLLP_MFP_DS_04X );
	//XllpMfpConfigurePullUpDown( (P_XLLP_VUINT32_T)v_pMFPRRegisters,  XLLP_MFP_CMMB_IRQ_OFFSET, XLLP_MFP_PULL_UP);
	//XllpMfpActivatePullUpDown((P_XLLP_VUINT32_T)v_pMFPRRegisters,XLLP_MFP_CMMB_IRQ_OFFSET,XLLP_ON);
	XllpGpioSetDirection((P_XLLP_GPIO_T)v_pGPIORegisters, XLLP_GPIO_CMMB_INT, XLLP_GPIO_DIRECTION_IN);
    XllpGpioSetFallingEdgeDetectEnable((P_XLLP_GPIO_T) v_pGPIORegisters, XLLP_GPIO_CMMB_INT, XLLP_ON);
	


	RETAILMSG(1, (TEXT("[Siano] loop 5s 111111\r\n")));	

   	Sleep(5000);
/*
	if(XLLP_STATUS_SUCCESS!=XllpGpioExpanderSetOutputLevel(v_pI2CRegisters,v_pOSTRegisters, XLLP_GPIO_TV_RESET, XLLP_HI ))
	{
		RETAILMSG(1, (_T("Set XLLP_GPIO_TV_POWERON HI Error\r\n")));
	}
	if(XLLP_STATUS_SUCCESS!=XllpGpioExpanderSetOutputLevel(v_pI2CRegisters,v_pOSTRegisters, XLLP_GPIO_TV_RESET, XLLP_LO ))
	{
		RETAILMSG(1, (_T("Set XLLP_GPIO_TV_POWERON LO Error\r\n")));
	}
	XllpOstDelayMilliSeconds(v_pOSTRegisters,20);
	if(XLLP_STATUS_SUCCESS!=XllpGpioExpanderSetOutputLevel(v_pI2CRegisters,v_pOSTRegisters, XLLP_GPIO_TV_RESET, XLLP_HI ))
	{
		RETAILMSG(1, (_T("Set XLLP_GPIO_TV_POWERON HI Error\r\n")));
	}
*/    
  
    switch (pSpiPhy->useSSPPort)
    {
    case 1:
	    RETAILMSG(1, (TEXT(" Phy_init XllpSSPMFPConfigure\r\n")));	

		
	    XllpSSPMFPConfigure(XLLP_SSP_LT_LCD,
        XLLP_TRUE,
        (XLLP_UINT32_T)v_pMFPRRegisters,
        (XLLP_SSP_REGISTER_T *)pSpiPhy->sspCtrl);
        break;


	case 2:
		 XllpSSPMFPConfigure(XLLP_SSP_CMMB,
        XLLP_TRUE,
        (XLLP_UINT32_T)v_pMFPRRegisters,
        (XLLP_SSP_REGISTER_T *)pSpiPhy->sspCtrl);
        break;
    case 3:

        break;
    default:
		break;
    }
	
#endif //CONFIGURE_GPIO
//////////////////////////////////////////////
//		CONFIGURING by SSP port
//////////////////////////////////////////////




	if (!enableDisableSSPClock(pSpiPhy, FALSE))
	{
        smsspiphy_deinit(pSpiPhy);
		return NULL;
	}

	// Set register SSCR0
	//pSpiPhy->sspCtrl->sscr0 |= XLLP_SSCR0_SSE;
	pSpiPhy->sspCtrl->sscr0 = SSCR0_Motorola | SSCR0_DataSize(16) | SSCR0_EDSS;//32bit words in the fifo
	pSpiPhy->sspCtrl->sscr0 |=1<<8; // Divide the clock by 2

	// Set register SSCR1
	pSpiPhy->sspCtrl->sscr1 = (SSCR1_TRAIL|SSCR1_RIE|SSCR1_TIE|SSCR1_RxTresh(1) | SSCR1_TxTresh(7)); 
	
	// Set register SSITR
	pSpiPhy->sspCtrl->ssitr = 0; 

	// Set register SSTO
	pSpiPhy->sspCtrl->ssto = 0; //No timeout. always send/recieve the same amount of bytes.

	if (!enableDisableSSPClock(pSpiPhy, TRUE))
	{
        smsspiphy_deinit(pSpiPhy);
		return NULL;
	}

	//Activate SSP channel
    pSpiPhy->sspCtrl->sscr0 |=XLLP_SSCR0_SSE;  // 1 -- SSP operation is enabled
#ifdef GET_GPIOXX_2_IRQ
	   

	SPICDSysIntr =  pSpiPhy->spiSysIntr;



//	DBGMSG( ZONE_INFO, (TEXT("SPI : InterruptInitialize(sysInt =%d, IRQ = %d)\r\n"), 
//               SPICDSysIntr, SPIINTIRQ));

	if (!InterruptInitialize(SPICDSysIntr,pSpiPhy->SmsInterruptEvent,0,0))
    {
        DBGMSG( ZONE_INFO, (TEXT("SPI : InterruptInitialize(sysInt =%d, Event=0x%x) failed (status =%d)\r\n"), 
                   pSpiPhy->spiSysIntr, pSpiPhy->SmsInterruptEvent, GetLastError()));
    }

	//Creating the ISR Thread and the IO notifying Event
#endif	

	MmUnmapIoSpace((PVOID)v_pMFPRRegisters,MFPR_MEMORY_SPACE);
	MmUnmapIoSpace((PVOID)v_pGPIORegisters,sizeof(XLLP_GPIO_T));
    MmUnmapIoSpace((PVOID)v_pOSTRegisters, sizeof(XLLP_OST_T));
	MmUnmapIoSpace((PVOID)v_pI2CRegisters,sizeof(XLLP_I2C_T));
	pSpiPhy->RxIST = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)SpiRxIST, pSpiPhy, 0, NULL);
	if (pSpiPhy->RxIST == NULL)
	{
		DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: smsspiphy_init() failed to create transferThread thread.\r\n")));
		smsspiphy_deinit(pSpiPhy);
		return 0;
	}
	if (CeSetThreadPriority(pSpiPhy->RxIST, 100) == FALSE)
	{
		DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: smsspiphy_init() failed to set Interrupt thread priority.\r\n")));
		smsspiphy_deinit(pSpiPhy);
		return 0;
	}

	return pSpiPhy;
}

void smschipreset(PVOID context)
{
	
}
